package com.swagger.demo.config;

import com.fasterxml.classmate.ResolvedType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import springfox.documentation.schema.ModelReference;
import springfox.documentation.schema.TypeNameExtractor;
import springfox.documentation.service.ResolvedMethodParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.contexts.ModelContext;
import springfox.documentation.spi.service.ParameterBuilderPlugin;
import springfox.documentation.spi.service.contexts.OperationContext;
import springfox.documentation.spi.service.contexts.ParameterContext;

import static springfox.documentation.schema.ResolvedTypes.modelRefFactory;
import static springfox.documentation.spi.schema.contexts.ModelContext.inputParam;

/**
 * @author honeypie
 * 把解析后的请求值类型填充到swagger文档中
 *
 * 参考代码：
 * <dependency>
 *     <groupId>com.github.xiaoymin</groupId>
 *     <artifactId>swagger-bootstrap-ui</artifactId>
 *     <version>1.9.6</version>
 * </dependency>
 * 此依赖中的DynamicParameterBuilderPlugin类
 *
 */
@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 10)
public class JsonViewRequestModelReader implements ParameterBuilderPlugin {


    private final TypeNameExtractor typeNameExtractor;

    @Autowired
    public JsonViewRequestModelReader(TypeNameExtractor typeNameExtractor) {
        this.typeNameExtractor = typeNameExtractor;
    }

    @Override
    public void apply(ParameterContext context) {
        ResolvedMethodParameter methodParameter = context.resolvedMethodParameter();

        OperationContext operationContext = context.getOperationContext();
        String pattern = operationContext.requestMappingPattern();
        String method = "[" + operationContext.httpMethod().name() + "]";
        String requestMappingPattern = pattern + method;
        // 拼接url、method和参数index得到缓存的key，比如：/addUser[POST]_P[0]
        requestMappingPattern = requestMappingPattern + "_P[" + methodParameter.getParameterIndex() + "]";

        if (OperationJsonViewModelProvider.urlModelRefCache.containsKey(requestMappingPattern)) {
            ResolvedType parameterType = OperationJsonViewModelProvider.urlModelRefCache.get(requestMappingPattern);
            ModelContext modelContext = inputParam(
                    context.getGroupName(),
                    parameterType,
                    context.getDocumentationType(),
                    context.getAlternateTypeProvider(),
                    context.getGenericNamingStrategy(),
                    context.getIgnorableParameterTypes());
            ModelReference modelRef = modelRefFactory(modelContext, typeNameExtractor).apply(parameterType);

            context.parameterBuilder()
                    .type(parameterType)
                    .modelRef(modelRef);
        }

    }

    @Override
    public boolean supports(DocumentationType delimiter) {
        return true;
    }

}
